<template>
	<div v-show="!closed">
		<commons-alert @alert-dismissed="alertDismissed" :variant="alert.variant" :dismissCountDown="alert.dismissCountDown">{{alert.message}}</commons-alert>
		<b-button v-if="closeable" size="sm" variant="dark" class="image-close-btn" @click="closeImageArea">
			<b-icon icon="x"></b-icon>
		</b-button>
		<div class="file-item-mask" :style="{'height': height / 16 + 'rem'}">
			<h4>拖文件至此可上传</h4>
			<b-button variant="primary" class="m-1">
				<b-icon icon="upload"></b-icon>
				上传文件(可多选)
			</b-button>
			<b-container v-if="showProgressInUploadArea" fluid>
				<b-row>
					<b-col class="overflow-hidden" cols="2" v-for="file in files" :key="file.name">
						{{file.name}}
						<b-progress :value="process[file.name]" max="100" show-progress animated></b-progress>
					</b-col>
				</b-row>
			</b-container>
		</div>
		<b-form-file :style="{'height': height / 16 + 'rem'}" class="file-item" :accept="accept" drop-placeholder="拖文件到此处上传" multiple v-model="files"
		 plain></b-form-file>
		<hr v-if="showProgressUnderUploadArea" />
		<slot name="before-under-area"></slot>
		<b-container v-if="showProgressUnderUploadArea" fluid>
			<b-row class="p-1 previews-item" v-for="file in allFiles" :key="file.name">
				<b-col cols="2">
					<img v-if="isImage(file.type)" class="image-previews" :src="urls[file.name]" />
					<a v-else class="file-previews" :href="urls[file.name]">
						<b-icon icon="files"></b-icon>
					</a>
				</b-col>
				<b-col cols="10">
					<div>{{file.name}}</div>
					<b-progress :value="process[file.name]" max="100" show-progress animated></b-progress>
				</b-col>
			</b-row>
		</b-container>
	</div>
</template>

<script>
	import axios from 'axios'
	import gl from '../commons/global_variable.js'
	import CommonsAlert from './Alert.vue'

	export default {
		name: "file-upload",
		components: {
			CommonsAlert
		},
		props: {
			closeable: {
				type: Boolean,
				default: false
			},
			height: {
				type: Number,
				default: 300
			},
			showProgressInUploadArea: {
				type: Boolean,
				default: true
			},
			showProgressUnderUploadArea: {
				type: Boolean,
				default: false
			},
			accept: {
				type: String,
				default: "*"
			}
		},
		data: function() {
			return {
				alert: {
					message: '',
					variant: 'warning',
					dismissCountDown: 0
				},
				closed: false,
				files: [],
				allFiles: [],
				process: {},
				urls: {}
			}
		},
		methods: {
			setCloseValue: function(value){
				this.closed = value
			},
			closeImageArea: function() {
				this.closed = true
				this.files = []
				this.allFiles = []
				this.$emit("file-upload-closed")
			},
			alertDismissed: function() {
				this.alert.dismissCountDown = 0
			},
			onUploadError: function() {
				this.alert.message = "上传文件失败"
				this.alert.dismissCountDown = 3
			},
			isImage: function(value) {
				return value.startsWith("image/")
			}
		},
		watch: {
			files: function(vals) {
				var that = this
				vals.map(function(val) {
					that.allFiles.unshift(val)
				})
				vals.forEach(it => {
					var formData = new FormData()
					formData.append('file', it)
					axios.post(gl.cms_args.server_url + 'media/save', formData, {
						headers: {
							'Content-Type': 'multipart/form-data'
						},
						onUploadProgress: function(progressEvent) {
							var complete = (progressEvent.loaded / progressEvent.total * 100 | 0)
							that.$set(that.process, it.name, complete)
						}
					}).then(function(response) {
						var res = response.data;
						if (res.code === gl.cms_args.success) {
							that.$set(that.urls, it.name, res.data.url)
							that.$emit("file-upload-success", {
								original: it,
								item: res.data
							})
						} else {
							that.$emit("file-upload-error", {
								original: it
							})
							that.onUploadError()
						}
					}).catch(function(error) {
						that.$emit("file-upload-error", {
							original: it
						})
						that.onUploadError()
					})
				})
			}
		}
	}
</script>

<style>
	.image-close-btn {
		position: absolute;
		right: 0;
		top: 0;
		z-index: 9999;
	}

	.file-item-mask {
		position: absolute;
		text-align: center;
		border: 0.1875rem dashed gray;
		right: 0;
		left: 0;
		overflow: auto;
	}

	.file-item {
		opacity: 0;
	}

	.image-previews {
		width: 3.125rem;
		height: 3.125rem;
	}

	.file-previews {
		display: block;
		text-align: center;
		font-size: 1.875rem;
		margin-top: 0.625rem;
	}

	.previews-item {
		border-bottom: 0.0625rem solid #282828;
	}
</style>
